﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using eTMS.Controllers;

namespace eTMS.Forms.Students
{
    public partial class FrmChonSinhVienVaoLop : eTMS.Controls.BaseForm
    {
        public FrmChonSinhVienVaoLop()
        {
            InitializeComponent();
        }

        private Dictionary<int, DataRow> dictionaryLopRow;
        public void SetDataRowLop(List<DataRow> rows)
        {
            if (rows.Count > 0)
            {
                lopController.Table = rows[0].Table.Clone();
                if (!lopController.Table.Columns.Contains("SucChua"))
                    lopController.Table.Columns.Add("SucChua", typeof(int));
                if (!lopController.Table.Columns.Contains("SoNam"))
                    lopController.Table.Columns.Add("SoNam", typeof(int));
                if (!lopController.Table.Columns.Contains("SoNamDuocPhep"))
                    lopController.Table.Columns.Add("SoNamDuocPhep", typeof(int));

                dictionaryLopRow = new Dictionary<int, DataRow>();
                foreach (DataRow row in rows)
                {
                    lopController.Table.ImportRow(row);
                    int soSV = lopController.ConvertInt(row["SoSinhVienToiDa"]) - lopController.ConvertInt(row["SoSinhVien"]);
                    DataRow r = lopController.Table.Rows[lopController.Table.Rows.Count - 1];
                    r["SucChua"] = soSV;
                    dictionaryLopRow.Add(lopController.ConvertInt(r["Lop_ID"]), r);
                }
                gridData.AutoGenerateColumns = false;
                gridData.DataSource = lopController.Table;
            }
        }

        SinhVienController sinhVienController = new SinhVienController();
        private LopController lopController = new LopController();
        private void FrmChonSinhVienVaoLop_Load(object sender, EventArgs e)
        {
            sinhVienList1.SetController(sinhVienController);
            sinhVienInfoInput1.SetController(sinhVienController);
            sinhVienList1.AddColumn("ColDiem", "Điểm thi", "DiemDuTuyen", 5, true);
        }
        private void btnChonSV_Click(object sender, EventArgs e)
        {
            sinhVienController.ResetObject();
            sinhVienInfoInput1.UpdateToModel();
            sinhVienController.SearchSinhVienChuaPhanLop(lopController.ConvertInt(lopController.Table.Rows[0]["NganhHoc_ID"]), lopController.ConvertInt(lopController.Table.Rows[0]["KhoaHoc_ID"]));
            sinhVienList1.UpdateToScreen();
            foreach (DataRow row in lopController.Table.Rows)
            {
                row["SoSinhVien"] = lopController.ConvertInt(row["SoSinhVienToiDa"]) - lopController.ConvertInt(row["SucChua"]);
            }
        }
        private void XepLopNgauNhien(List<DataRow> listSinhVien)
        {
            List<int> lsIndexs = new List<int>();
            List<int> lsKeys = new List<int>(dictionaryLopRow.Keys);
            InitData(lsKeys, lsIndexs, listSinhVien);
            while ((lsIndexs.Count > 0) && (lsKeys.Count > 0))
            {
                for (int i = 0; i < lsKeys.Count; i++)
                {
                    if (lsIndexs.Count == 0) break;
                    int key = lsKeys[i];
                    if (lopController.ConvertInt(dictionaryLopRow[key]["SoSinhVienToiDa"]) - lopController.ConvertInt(dictionaryLopRow[key]["SoSinhVien"]) <= 0)
                    {
                        lsKeys.RemoveAt(i);
                        i--;
                        continue;
                    }
                    int currentIndex = 0;
                    int soNam = lopController.ConvertInt(dictionaryLopRow[key]["SoNam"]);
                    int soNamDuocPhep = lopController.ConvertInt(dictionaryLopRow[key]["SoNamDuocPhep"]);
                    if ((!cbkCanBangNamNu.Checked) || (soNam < soNamDuocPhep))
                    {
                        Random random = new Random(DateTime.Now.Millisecond);
                        currentIndex = random.Next(lsIndexs.Count);
                    }
                    else
                    {
                        currentIndex = RandIndexGioiTinh(lsIndexs, listSinhVien, false);
                    }
                    AssignSVToLop(listSinhVien[lsIndexs[currentIndex]], dictionaryLopRow[key], dictionaryLopRow);
                    lsIndexs.RemoveAt(currentIndex);
                }
            }
        }
        private int RandIndexGioiTinh(List<int> lsIndexs, List<DataRow> lsRow, bool IsNam)
        {
            List<int> lsIn = new List<int>();
            foreach (int i in lsIndexs)
            {
                bool isNam = lopController.ConvertInt(lsRow[i]["GioiTinh"]) == 1;
                if ((IsNam && isNam) || ((!IsNam) && (!isNam)))
                {
                    lsIn.Add(i);
                }
            }
            Random random = new Random(DateTime.Now.Millisecond);

            if (lsIn.Count > 0)
            {
                int index = random.Next(lsIn.Count);
                return lsIndexs.IndexOf(lsIn[index]);
            }
            return random.Next(lsIndexs.Count);
        }
        private void InitData(List<int> lsKeys, List<int> lsIndexs, List<DataRow> listSinhVien)
        {
            int TongSoNam = 0;
            int TongSoXep = 0;
            foreach (DataRow row in lopController.Table.Rows)
            {
                int countInLop = 0;
                int Lop_ID = lopController.ConvertInt(row["Lop_ID"]);
                foreach (DataRow sinhVien in listSinhVien)
                {
                    if (lopController.ConvertInt(sinhVien["Lop_ID"]) == Lop_ID)
                    {
                        countInLop++;
                    }
                }
                row["SoNam"] = 0;
                int SoSVToiDa = lopController.ConvertInt(row["SoSinhVienToiDa"]);
                int soSV = SoSVToiDa - lopController.ConvertInt(row["SoSinhVien"]);
                if (soSV + countInLop > 0)
                {
                    TongSoXep += SoSVToiDa;
                    lsKeys.Add(Lop_ID);
                }
            }
            for (int i = 0; i < listSinhVien.Count; i++)
            {
                lsIndexs.Add(i);
                if (cbkCanBangNamNu.Checked)
                {
                    if (lopController.ConvertInt(listSinhVien[i]["GioiTinh"]) == 1)
                    {
                        TongSoNam++;
                    }
                }
            }
            foreach (int key in lsKeys)
            {
                DataRow row = dictionaryLopRow[key];
                int SoSVToiDa = lopController.ConvertInt(row["SoSinhVienToiDa"]);
                int soSV = SoSVToiDa - lopController.ConvertInt(row["SoSinhVien"]);
                row["SoNamDuocPhep"] = (int)((double)soSV * (double)TongSoNam / (double)listSinhVien.Count);
            }

        }
        private bool CheckCanBangNamNu(DataRow row, DataRow rowSinhVien)
        {
            if (cbkCanBangNamNu.Checked)
            {
                int soNam = lopController.ConvertInt(row["SoNam"]);
                int soNamDuocPhep = lopController.ConvertInt(row["SoNamDuocPhep"]);
                bool IsNam = lopController.ConvertInt(rowSinhVien["GioiTinh"]) == 1;
                if (IsNam && soNam > soNamDuocPhep)
                {
                    return false;
                }
                if (IsNam)
                {
                    row["SoNam"] = soNam++;
                }
            }
            return true;
        }
        private void XepLopTheoThuTuQuayVong(List<DataRow> listSinhVien)
        {
            List<int> lsIndexs = new List<int>();
            List<int> lsKeys = new List<int>();
            InitData(lsKeys, lsIndexs, listSinhVien);
            for (int j = 0; j < lsIndexs.Count; j++)
            {
                if (lsKeys.Count == 0) break;
                int indexSV = lsIndexs[j];
                for (int i = 0; i < lsKeys.Count; i++)
                {
                    int key = lsKeys[i];
                    if (!CheckCanBangNamNu(dictionaryLopRow[key], listSinhVien[indexSV])) continue;
                    AssignSVToLop(listSinhVien[indexSV], dictionaryLopRow[key], dictionaryLopRow);
                    if (lopController.ConvertInt(dictionaryLopRow[key]["SoSinhVienToiDa"]) - lopController.ConvertInt(dictionaryLopRow[key]["SoSinhVien"]) <= 0)
                    {
                        lsKeys.RemoveAt(i);
                        i--;
                    }
                    j++;
                    if (j >= lsIndexs.Count) break;
                }
                j--;
            }
        }
        private void XepLopTheoThuTuLanLuot(List<DataRow> listSinhVien)
        {
            List<int> lsIndexs = new List<int>();
            List<int> lsKeys = new List<int>(dictionaryLopRow.Keys);
            InitData(lsKeys, lsIndexs, listSinhVien);
            for (int i = 0; i < lsKeys.Count; i++)
            {
                if (lsKeys.Count == 0) break;
                int key = lsKeys[i];
                if (lopController.ConvertInt(dictionaryLopRow[key]["SoSinhVienToiDa"]) - lopController.ConvertInt(dictionaryLopRow[key]["SoSinhVien"]) <= 0)
                {
                    lsKeys.RemoveAt(i);
                    i--;
                    continue;
                }
                while (lsIndexs.Count > 0)
                {
                    int indexSV = lsIndexs[0];
                    if (!CheckCanBangNamNu(dictionaryLopRow[key], listSinhVien[indexSV])) continue;
                    AssignSVToLop(listSinhVien[indexSV], dictionaryLopRow[key], dictionaryLopRow);
                    lsIndexs.RemoveAt(0);
                    if (lopController.ConvertInt(dictionaryLopRow[key]["SoSinhVienToiDa"]) - lopController.ConvertInt(dictionaryLopRow[key]["SoSinhVien"]) <= 0)
                    {
                        break;
                    }
                }
            }
        }

        private void AssignSVToLop(DataRow sinhVienRow, DataRow lopRow, Dictionary<int, DataRow> dictionaryLopRow)
        {
            int oldLop_ID = lopController.ConvertInt(sinhVienRow["Lop_ID"]);
            if (oldLop_ID > 0)
            {
                dictionaryLopRow[oldLop_ID]["SoSinhVien"] = lopController.ConvertInt(dictionaryLopRow[oldLop_ID]["SoSinhVien"]) - 1;
            }
            lopRow["SoSinhVien"] = lopController.ConvertInt(lopRow["SoSinhVien"]) + 1;
            sinhVienRow["Lop_ID"] = lopRow["Lop_ID"];
            sinhVienRow["MaLop"] = lopRow["MaLop"];
            sinhVienRow["TenLop"] = lopRow["TenLop"];
        }

        private void btnXepLopTheoNgauNhien_Click(object sender, EventArgs e)
        {
            XepLopNgauNhien(sinhVienList1.GetSelectedSinhVienRows());
        }

        private void btnXepLopTheoThuTu_Click(object sender, EventArgs e)
        {
            XepLopTheoThuTuQuayVong(sinhVienList1.GetSelectedSinhVienRows());
        }

        private void btnXepLopLanLuot_Click(object sender, EventArgs e)
        {
            XepLopTheoThuTuLanLuot(sinhVienList1.GetSelectedSinhVienRows());
        }

        private void ucCommandDialog1_OnOK(object sender, CancelEventArgs e)
        {
            sinhVienController.PhanLopChoSinhVien();
        }
    }
}
